<?php
/**
 * @link      https://www.zhongan.com
 * @copyright Copyright (c) 2016 众安保险
 */

/**
 * 众安收银台支付类 （注：仅做示例使用，具体使用请自行优化）
 *
 * 调用须知：
 * createPayUrl和validationSign分别调用之前请先setConfig来设定配置
 */
namespace MobileHome\Controller;

class ZaCashierPay
{
    private static $_apiUrl;            //接口地址
    private static $_mechantCode;       //商户编码
    private static $_appKey;            //appkey
    private static $_error;             //错误信息


    /**
     * 配置请求         [step: 1]
     * @param $config
     * @return bool
     */
    public static function setConfig($config){
        if(!$config || !$config['url'] || !$config['mechantCode'] || !$config['appKey']){
            self::$_error='基础配置有误';
            return false;
        }
        self::$_apiUrl=$config['url'];
        self::$_mechantCode=$config['mechantCode'];
        self::$_appKey=$config['appKey'];

        return true;
    }


    /**
     * 获取支付url（支付前使用）
     * @param $params
     * @return string
     */
    public static function createPayUrl($params){
        if(!self::_validationConfig()){
            return false;
        }
        $params['sign']=self::_paramsToSign($params);

        $queryStr=self::_myHttpBuildQuery($params);

        return self::$_apiUrl.'?'.$queryStr;
    }


    /**
     * 验证签名（支付回调使用）
     * @param $params
     * @return bool
     */
    public static function validationSign($params){
        if(!self::_validationConfig()){
            return false;
        }
        $requestSign=$params['sign'];

        $mySign=self::_paramsToSign($params);
        if($requestSign!==$mySign){
            self::$_error='签名错误';
            return false;
        }
        return true;
    }


    /**
     * 获取错误信息
     * @return mixed
     */
    public static function getError(){
        return self::$_error;
    }


    /**
     * 合成queryString
     * @param $params
     * @return string
     */
    private static function _myHttpBuildQuery($params){
        $queryStr='';
        foreach($params as $paramsK=>$paramsV){
            $queryStr.=$paramsK.'='.$paramsV.'&';
        }
        $queryStr=trim($queryStr,'&');

        return $queryStr;
    }

    /**
     * 验证基础配置（这里处理比较粗暴，可以按照自己的方式来灵活处理）
     * @return bool
     */
    private static function _validationConfig(){
        if(!self::$_apiUrl || !self::$_mechantCode || !self::$_appKey){
            self::$_error='配置有误';
            return false;
        }
        return true;
    }


    /**
     * 合成sign
     * @param $params   参数数组
     * @return string
     */
    private static function _paramsToSign($params){
        if(isset($params['sign'])){
            unset($params['sign']);
        }
        if(isset($params['sign_type'])){
            unset($params['sign_type']);
        }
        ksort($params);
        $queryStr=self::_myHttpBuildQuery($params);
        $queryStr=$queryStr . self::$_appKey;
        $queryStr=md5($queryStr);
        return $queryStr;
    }
}



///**
// * 自己的处理类 （注：仅做示例使用，具体使用请自行优化）
// * Class Demo
// */
//class Demo
//{
//    private $_config;
//
//
//    /**
//     * 构造
//     * Pay constructor.
//     * @param $env      项目环境dev/test/prod
//     */
//    public function __construct($env)
//    {
//        /**
//         * 配置信息,暂时区分开发、测试、生产，如有其他环境请自行配置
//         * （请自行做好其他方式的灵活配置，如：放入配置文件等）
//         * 配置信息参见文档，或咨询对接人员。
//         */
//        $cashier=[
//            'dev'=>[
//                'url'=>'http://xxxxx/za-cashier-web/gateway.do',
//                'mechantCode'=>'xxxxx',
//                'appKey'=>'xxxxx'
//            ],
//            'test'=>[
//                'url'=>'http://xxxxx/za-cashier-web/gateway.do',
//                'mechantCode'=>'xxxxx',
//                'appKey'=>'xxxxx'
//            ],
//            'prod'=>[
//                'url'=>'http://xxxxx/za-cashier-web/gateway.do',
//                'mechantCode'=>'xxxxx',
//                'appKey'=>'xxxxx'
//            ]
//        ];
//
//        $this->_config=$cashier[$env];
//    }
//
//
//    /**
//     * 进行支付
//     */
//    public function pay(){
//        //这里组合请求参数，请求参数详解请参见文档
//        //另：某些参数非必传，记得去掉该参数。传空值会导致验签失败。参数值请不要放入奇怪符号如：#、%等。
//        $requestData=[
//            'request_charset'=>'UTF-8',                             //编码
//            'sign_type'=>'MD5',                                     //签名方式
//            'out_trade_no'=>'12345567abc',                          //商户订单号
//            'merchant_code'=>$this->_config['mechantCode'],         //商户号
//            'subject'=>'XXX保险',                                   //产品名称
//            'body'=>'描述',                                         //产品描述
//            'amt'=>1,                                               //支付金额 单位:元
//            'expiry_time'=>30,                                      //订单有效时间  单位：分钟
//            'pay_channel'=>'alipay^wxpay^anthb',                    //支付渠道：默认全开通 alipay^wxpay^anthb
//            'src_type'=>'mobile',                                   //来源类型 pc/mobile   电脑端/移动端
//            'order_type'=>'insurance',                              //订单类型：默认保险订单
//            'show_url'=>'http://www.xxx.com',                       //商品地址
//            'notify_url'=>'http://www.xxx.com',                     //服务器通知回调url
//            'back_url'=>'http://www.xxx.com',                       //关闭跳转return_url
//            'return_url'=>'http://www.xxx.com',                     //前端跳转url
//            'notify_info'=>'{"a":"abcxyz","b":"XXXX","c":"9.00"}',  //公用回传参数  json格式
//            'order_info'=>'{"被保人":"XXX","保险期限":"XXXX"}',       //产品详情  json格式
//        ];
//
//        //设置配置
//        if(!ZaCashierPay::setConfig($this->_config)){
//            exit(ZaCashierPay::getError());
//        }
//        //获取支付url
//        $redirectPayUrl=ZaCashierPay::createPayUrl($requestData);//获取支付url后，跳转过去就ok了。
//        if(!$redirectPayUrl){
//            exit(ZaCashierPay::getError());
//        }
//        //执行跳转，或返回url然后进行其他操作后跳转
//    }
//
//
//    /**
//     * 通知回调
//     */
//    public function notify(){
//        $notifyData=$_POST; //接收的get或post的参数
//
//        //设置配置
//        if(!ZaCashierPay::setConfig($this->_config)){
//            exit('fail');
//        }
//        //验证签名
//        if(!ZaCashierPay::validationSign($notifyData)){
//            exit('fail');
//        }
//        //支付失败
//        if($notifyData['pay_result'] !== 'S') {
//            //失败后续操作
//        }
//
//        //进行其他自主操作，如判定支付状态、处理订单状态等
//
//        exit('success');
//    }
//
//
//    /**
//     * 跳转回调
//     */
//    public function returnUrl(){
//        $notifyData=$_GET; //接收的get或post的参数
//
//        //设置配置
//        if(!ZaCashierPay::setConfig($this->_config)){
//            exit('失败');
//        }
//        //验证签名
//        if(!ZaCashierPay::validationSign($notifyData)){
//            exit('失败');
//        }
//        //支付失败
//        if($notifyData['pay_result'] !== 'S') {
//            //失败后续操作
//        }
//
//        //进行其他自主操作，如判定支付状态、处理订单状态等
//
//    }
//}
//
///**********************下面可以使用了*******************************/
////实例化
//$Demo=new Demo('dev');
////支付
//$Demo->pay();
////回调
//$Demo->returnUrl();
//$Demo->notify();
